#include "ImageFinder.h"
#include <opencv2/opencv.hpp>
#include <windows.h>

// 截取屏幕指定区域
cv::Mat CaptureScreen(int x, int y, int w, int h)
{
    HDC hScreenDC   = GetDC(NULL);
    HDC hMemoryDC   = CreateCompatibleDC(hScreenDC);
    HBITMAP hBitmap = CreateCompatibleBitmap(hScreenDC, w, h);
    SelectObject(hMemoryDC, hBitmap);
    BitBlt(hMemoryDC, 0, 0, w, h, hScreenDC, x, y, SRCCOPY | CAPTUREBLT);

    BITMAP bitmap;
    GetObject(hBitmap, sizeof(BITMAP), &bitmap);

    cv::Mat mat(bitmap.bmHeight, bitmap.bmWidth, CV_8UC4, bitmap.bmBits);
    cv::cvtColor(mat, mat, cv::COLOR_BGRA2BGR);
    cv::flip(mat, mat, 0);  // 翻转图像行顺序

    DeleteObject(hBitmap);
    DeleteDC(hMemoryDC);
    ReleaseDC(NULL, hScreenDC);

    return mat.clone();
}

extern "C" IMAGEFINDER_API bool __stdcall FindImage(const char *targetPath,
                                                    int searchX,
                                                    int searchY,
                                                    int searchW,
                                                    int searchH,
                                                    int *x,
                                                    int *y)
{
    // 截取屏幕区域
    cv::Mat screenMat = CaptureScreen(searchX, searchY, searchW, searchH);
    if (screenMat.empty())
        return false;

    // 读取目标图像
    cv::Mat templateMat = cv::imread(targetPath, cv::IMREAD_COLOR);
    if (templateMat.empty())
        return false;

    // 检查模板尺寸
    if (templateMat.cols > screenMat.cols || templateMat.rows > screenMat.rows)
        return false;

    // 转换为灰度图
    cv::Mat screenGray, templateGray;
    cv::cvtColor(screenMat, screenGray, cv::COLOR_BGR2GRAY);
    cv::cvtColor(templateMat, templateGray, cv::COLOR_BGR2GRAY);

    // 模板匹配
    cv::Mat result;
    cv::matchTemplate(screenGray, templateGray, result, cv::TM_CCOEFF_NORMED);

    double minVal, maxVal;
    cv::Point minLoc, maxLoc;
    cv::minMaxLoc(result, &minVal, &maxVal, &minLoc, &maxLoc);

    const double threshold = 0.8;
    if (maxVal >= threshold)
    {
        *x = searchX + maxLoc.x;
        *y = searchY + maxLoc.y;
        return true;
    }
    return false;
}